<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h1 id="hh">{{msg}}</h1>
        <child />
    </div>
</body>

</html>
<script src='https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js'></script>
<script>
    //组件嵌套:

    //组件初始化的时候:
    //父子组件嵌套的时候:以beforeMount为分界点,父组件执行到beforeMount的时候,开始执行子组件的钩子函数,等到子组件的mounted执行完成之后,再执行父组件的mounted

    //组件更新的时候,只会触发当前实例(组件)的更新函数 beforeUpdate updated

    //卸载的时候:先执行父组件的beforeDestroy再执行子组件的beforeDestroy destroyed 最后执行父组件的destroyed

    //钩子函数要弄清楚的问题

    //1.钩子函数逇执行顺序

    //2.哪里能操作dom

    //3.哪里能发送请求

    //4.哪里能操作数据

    let vm = new Vue({
        data: {
            msg: '你吃了嘛'
        },
        //创建之前
        beforeCreate() {
            //初始化事件,初始化生命周期,组件创建出来只会执行一次
            console.group('beforeCreate')
            //输出组件的数据
            console.log('$data====', this.$data)
            //输出vue根据模板创建出来的dom(虚拟dom)结构
            console.log('$el=====', this.$el)
            console.log('hh的innerText', document.getElementById('hh').innerText)
            console.groupEnd()
        },
        //创建之后
        created() {
            //可以发送异步请求
            //注入数据,并且对数据进行了劫持和响应,组件创建出来只会执行一次
            //在这里data methods computed都可以使用了
            //在这里不能操作dom
            console.group('created')
            //输出组件的数据
            console.log('$data====', this.$data)
            //输出vue根据模板创建出来的dom(虚拟dom)结构
            console.log('$el=====', this.$el)
            console.log('hh的innerText', document.getElementById('hh').innerText)
            console.groupEnd()
        },
        //挂载之前
        beforeMount() {
            //可以发送异步请求
            //会根据模板的内容,在内存中创建虚拟dom,组件(实例)创建出来只会执行一次
            //虚拟dom已经被创建了,但是里面的指令和插值表达式中的数据都没有被编译解析
            //不能操作dom,因为虚拟Dom还没有替换掉模板中的dom结构
            console.group('beforeMount')
            //输出组件的数据
            console.log('$data====', this.$data)
            //输出vue根据模板创建出来的dom(虚拟dom)结构
            console.log('$el=====', this.$el)
            console.log('hh的innerText', document.getElementById('hh').innerText)
            console.groupEnd()
        },
        // 挂载之后
        mounted() {
            //可以发送异步请求
            //会将创建出来并且编译好的虚拟dom,直接替换掉模板里面的结构,组件(实例)创建出来只会执行一次
            //可以操作dom,这里的虚拟Dom已经进行了编译,替换掉了原来模板中的结构
            console.group('moutned')
            //输出组件的数据
            console.log('$data====', this.$data)
            //输出vue根据模板创建出来的dom(虚拟dom)结构
            console.log('$el=====', this.$el)
            console.log('hh的innerText', document.getElementById('hh').innerText)
            console.groupEnd()

            this.interval = setInterval(() => {
                console.log('你看我头像牛逼嘛')
            }, 1000)
        },
        //更新之前
        beforeUpdate() {
            //只要数据变更就会触发,数据更新之前触发,可以触发多次
            console.group('beforeUpdate')
            //输出组件的数据
            console.log('$data====', this.$data)
            //输出vue根据模板创建出来的dom(虚拟dom)结构
            console.log('$el=====', this.$el)
            console.log('hh的innerText', document.getElementById('hh').innerText)
            console.groupEnd()
        },
        //更新之后
        updated() {
            //数据更新之后触发,只要数据变更就会触发,可以触发多次
            console.group('updated')
            //输出组件的数据
            console.log('$data====', this.$data)
            //输出vue根据模板创建出来的dom(虚拟dom)结构
            console.log('$el=====', this.$el)
            console.log('hh的innerText', document.getElementById('hh').innerText)
            console.groupEnd()
        },
        // 销毁之前
        beforeDestroy() {
            //什么情况下会触发组件的挂载卸载?
            //v-if切换组件显示的时候,会重新触发组件的生命周期钩子函数
            //动态组件
            //主动调用$destroy

            //一般在这里面会编写:清除定时器 一些持续性的事件监听 比如video监听播放进度的事件
            clearInterval(this.interval)
            console.group('beforeDestroy')
            console.groupEnd()
        },
        //销毁之后
        destroyed() {
            console.group('destroyed')
            console.groupEnd()
        },
        components: {
            child: {
                template: "<h1>子组件</h1>",
                beforeCreate() { 
                    console.log('子组件的befreCreate')
                },
                created() { 
                    console.log('子组件的created')
                },
                beforeMount() { 
                    console.log("子组件的beforeMount")
                },
                mounted() { 
                    console.log('子组件的mounted')
                },
                beforeUpdate() { 
                    console.log('子组件的beforeUpdate')
                },
                updated() {
                    console.log('子组件的updated')
                 },
                beforeDestroy() { 
                    console.log('子组件beforeDestroy')
                },
                destroyed() { 
                    console.log('子组件的destroyed')
                }
            }
        }
    }).$mount('#app')
</script>